 

package com.zdkj.subway.check.controller.subwayRat.swAuTvm;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zdkj.common.core.util.R;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.check.controller.CommonController;
import com.zdkj.subway.check.entity.*;
import com.zdkj.subway.check.enums.ResultDetailMsg;
import com.zdkj.subway.check.mapper.SwAuConductorNoticeMapper;
import com.zdkj.subway.check.mapper.SwAuTvmAmountDefferenceMapper;
import com.zdkj.subway.check.mapper.SwAuTvmNoticeMapper;
import com.zdkj.subway.check.mapper.SwAuTvmShortMapper;
import com.zdkj.subway.check.result.Result;
import com.zdkj.subway.check.service.SwAuTvmNoticeService;
import com.zdkj.subway.check.util.CheckAccount;
import com.zdkj.subway.check.util.DateFormat;
import com.zdkj.subway.check.util.JdbcUtil;
import com.zdkj.subway.check.util.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * TVM票款差异确认通知
 *
 * @author zhangxy
 * @date 2024-12-18 14:02:32
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/swautvmnotice" )
@Api(value = "swautvmnotice", tags = "TVM票款差异确认通知管理")
public class SwAuTvmNoticeController {

    @Autowired
    private SwAuTvmNoticeService swAuTvmNoticeService;
    @Autowired
    private SwAuTvmNoticeMapper swAuTvmNoticeMapper;
    @Resource
    SwAuConductorNoticeMapper swAuConductorNoticeMapper;
    @Autowired
    private SwAuTvmShortMapper swAuTvmShortMapper;
    @Autowired
    private CommonController commonController;
    @Autowired
    private SwAuTvmAmountDefferenceMapper swAuTvmAmountDefferenceMapper;

    /**
     * 分页查询
     * @param page 分页对象
     * @param param TVM票款差异确认通知
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @RequestMapping("/page" )
    public Page getSwAuTvmNoticePage(Page page, @RequestParam Map<String,String> param) {
        List<Map<String,Object>> res = swAuTvmNoticeMapper.getSwAuTvmNoticeList(param);
        page.setData(res,true);
        return page;
    }

    @RequestMapping("/getSwAuTvmNoticeList")
    @ApiOperation(value = "TVM票款差异通知 列表", notes = "TVM票款差异通知 列表")
    public Result getSwAuTvmNoticeList(@RequestBody JSONObject jsonObject) {
        return swAuTvmNoticeService.getSwAuTvmNoticeList(jsonObject);
    }

    @RequestMapping("affirmSwAuTvmNotice")
    @ApiOperation(value = "TVM票款差异通知 确认", notes = "TVM票款差异通知 确认")
    public R affirmSwAuTvmNotice(Integer id, String remark){
        SwAuTvmNotice byId = swAuTvmNoticeService.getById(id);
        Map<String,String> name = swAuConductorNoticeMapper.selUser(byId.getCreatorName());
        SwAuTvmNotice s = new SwAuTvmNotice();
        s.setId(id);
        s.setAppealStatus("6");
        s.setAuditSate("2");
        s.setApproverName(name.get("nikename"));
        s.setApproverJob(byId.getCreatorName()); // userCode
        s.setApproverTime(new Date());
        s.setRemark(remark);
        return R.ok(this.setAppealReply(String.valueOf(id), s));
    }

    @RequestMapping("recallTvmNotice")
    @ApiOperation(value = "TVM票款差异通知 撤回确认", notes = "TVM票款差异通知 撤回确认")
    public R recallTvmNotice(Integer id){
        SwAuTvmNotice s = new SwAuTvmNotice();
        s.setId(id);
        s.setAppealStatus("1");
        s.setAuditSate("1");
        s.setApproverName(null);
        s.setApproverJob(null);
        s.setApproverTime(null);
        s.setRemark(null);
        swAuTvmNoticeMapper.updateById(s);
        return R.ok();
    }

    @RequestMapping("updateSwAuTvmNotice")
    @ApiOperation(value = "TVM票款差异通知 申诉", notes = "TVM票款差异通知 申诉")
    public Result updateSwAuTvmNotice(@RequestBody JSONObject jsonObject){
        return swAuTvmNoticeService.updateSwAuTvmNotice(jsonObject);
    }

    @RequestMapping("/recallAppealSwAuTvmNotice")
    @ApiOperation(value = "TVM票款差异通知 撤回申诉", notes = "TVM票款差异通知 撤回申诉")
    public Result recallAppealSwAuTvmNotice(String ids){
        Result res=new Result(ResultDetailMsg.OK);
        try {
            List<SwAuTvmNotice> swAuTvmNotices = swAuTvmNoticeMapper.selectBatchIds(Arrays.asList(ids.split(",")));
            for (SwAuTvmNotice swAuTvmNotice : swAuTvmNotices) {
                SwAuTvmNotice s = new SwAuTvmNotice();
                s.setId(swAuTvmNotice.getId());
                s.setFileUrl("");
                s.setAppealStatus("1");
                s.setAppealType("");
                s.setAppealReason("");
                s.setOvertimeReason("");
                swAuTvmNoticeMapper.updateById(s);
            }
        } catch (Exception e){
            log.error("{}",e);
            res.setMsg("上传异常");
            res.setResult(ResultDetailMsg.CHECK_UPDATE_ERROR);
        }
        return res;
    }


    @PostMapping("subAuditSwAuTvmNotice")
    @ApiOperation(value = "TVM提交", notes = "TVM提交")
    public Result subAuditSwAuTvmNotice(@RequestBody SwAuTvmNotice swAuTvmNotice) {
        return swAuTvmNoticeService.subAuditSwAuTvmNotice(swAuTvmNotice);
    }

    @PostMapping("auditSwAuTvmrNotice")
    @ApiOperation(value = "审核", notes = "审核")
    public Result auditSwAuTvmrNotice(@RequestBody SwAuTvmNotice swAuTvmNotice) {
        return swAuTvmNoticeService.auditSwAuTvmrNotice(swAuTvmNotice);
    }

    /**
     * 下发
     * @param param
     * @return
     */
    @RequestMapping("/sendStatusUpdate")
    @ApiOperation(value = "下发", notes = "下发")
    @Transactional(rollbackFor = Exception.class)
    public Result sendStatusUpdate(@RequestBody Map<String,Object> param) {
        String ids = String.valueOf(param.get("ids"));
        Result res=new Result(ResultDetailMsg.OK);
        try {
            UpdateWrapper<SwAuTvmNotice> updateWrapper = new UpdateWrapper<>();
            updateWrapper.in("id", ids.split(","));
            SwAuTvmNotice swAuTvmNotice=new SwAuTvmNotice();
            swAuTvmNotice.setSendStatus(String.valueOf(param.get("sendStatus")));
            swAuTvmNotice.setSendTime(new Date()); //下发时间
            swAuTvmNotice.setAppealStatus("1"); //下发时默认待申诉
            swAuTvmNoticeMapper.update(swAuTvmNotice,updateWrapper);

            //根据不同类型发代办
            commonController.innerBatch(param);
        }catch (Exception e){
            log.error("{}",e);
            res.setMsg("下发失败");
            res.setResult(ResultDetailMsg.CHECK_UPDATE_ERROR);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return res;
    }

    @RequestMapping("/setAppealReply")
    @ApiOperation(value = "审批", notes = "审批")
    public Result setAppealReply(String ids, SwAuTvmNotice swAuTvmNotice) {
        Result res=new Result(ResultDetailMsg.OK);
        try {
            if (swAuTvmNotice.getApproverName()==null){
                PigxUser user = SecurityUtils.getUser();
                swAuTvmNotice.setApproverName(user.getNikeName());//审批人
                swAuTvmNotice.setApproverJob(user.getUserCode());//审批人工号
                swAuTvmNotice.setApproverTime(new Date());//审批时间
            }
            if ("11".equals(swAuTvmNotice.getAuditSate())&&!"6".equals(swAuTvmNotice.getAppealStatus())){
                swAuTvmNotice.setAppealStatus("3");//申诉成功
            } else if ("12".equals(swAuTvmNotice.getAuditSate())&&!"6".equals(swAuTvmNotice.getAppealStatus())){
                swAuTvmNotice.setAppealReply("4");//申诉失败
            }
            UpdateWrapper<SwAuTvmNotice> updateWrapper = new UpdateWrapper<>();
            updateWrapper.in("id",ids.split(","));
            swAuTvmNoticeMapper.update(swAuTvmNotice,updateWrapper);
            //
            if ("11".equals(swAuTvmNotice.getAuditSate())){
                LambdaQueryWrapper<SwAuTvmShort> wrapper =
                        Wrappers.<SwAuTvmShort>lambdaQuery().in(SwAuTvmShort::getNoticeId, Arrays.asList(ids.split(",")));
                swAuTvmShortMapper.delete(wrapper);
            }
            if("12".equals(swAuTvmNotice.getAuditSate())){//审批不通过

                List<SwAuTvmNotice> swAuTvmNotices = swAuTvmNoticeMapper.selectBatchIds(Arrays.asList(ids.split(",")));
                for (SwAuTvmNotice s:swAuTvmNotices){
                    SwAuTvmShort swAuTvmShort =new SwAuTvmShort();
                    swAuTvmShort.setNoticeId(s.getId());
                    swAuTvmShort.setDiffId(s.getRelationid());
                    swAuTvmShort.setLineCode(s.getLineCode());
                    swAuTvmShort.setStationCode(s.getStationCode());
                    swAuTvmShort.setNoticeType(s.getNoticeType());
                    swAuTvmShort.setRecordTime(s.getRecordTime());
                    swAuTvmShort.setTvmCode(s.getTvmCode());
                    swAuTvmShort.setConductorPersonCode(s.getConductorPersonCode());
                    swAuTvmShort.setConductorPersonName(s.getConductorPersonName());
                    if (s.getNoticeType().equals("2")) {
                        //钱箱类型
                        swAuTvmShort.setCashBoxType(s.getCashBoxType());
                    }
                    QueryWrapper<SwAuTvmShort> query = Wrappers.query(swAuTvmShort);
                    SwAuTvmShort selectOne = swAuTvmShortMapper.selectOne(query);
                    if(ObjectUtil.isNotEmpty(selectOne)){
                        swAuTvmShort.setId(selectOne.getId());
                    }
                    String dateExStr = DateFormat.date_ex_str(s.getRecordTime());
                    String sql="select date_add(a.END_TIME,interval 1 second) startSettleDate,date_add(a.END_TIME,interval (ifnull(b.TVM_SETTLEMENT_TERM,1))-1 day) endSettleDate\n" +
                            " from SW_CK_DATA_SUBMIT a\n" +
                            " left join sw_pm_long_period_settlement b on  a.LINE_CODE = b.LINE_CODE  and a.STATION_CODE = b.STATION_CODE and b.DEL_FLAG = '0'\n" +
                            " where  a.LINE_CODE = '"+s.getLineCode()+"'\n" +
                            " and a.STATION_CODE = '"+s.getStationCode()+"'\n"+
                            " and '"+dateExStr+"' BETWEEN  DATE_FORMAT(date_add(a.END_TIME,interval 1 second),'%Y-%m-%d') and DATE_FORMAT(date_add(a.END_TIME,interval (ifnull(b.TVM_SETTLEMENT_TERM,1))-1 day),'%Y-%m-%d')";
                    List<Map<String, Object>> r = JdbcUtil.exeSqlQuery(sql);
                    Date startTime=new Date();
                    Date endTime=new Date();
                    if(r!=null && r.size()>0){//不是历史的收益日期
                        startTime=(Date) (r.size()>0?r.get(0).get("startSettleDate"):startTime);
                        endTime=(Date) (r.size()>0?r.get(0).get("endSettleDate"):endTime);

                    }else{
                        sql = "select a.BEGIN_TIME startSettleDate," +
                                " date_add(a.END_TIME,interval -1 day) endSettleDate" +
                                " from sw_ck_data_submit_log a " +
                                " where  a.LINE_CODE =  '"+s.getLineCode()+"'" +
                                " and a.STATION_CODE = '"+s.getStationCode()+"'"+
                                " and  '"+dateExStr+"' BETWEEN  DATE_FORMAT(a.BEGIN_TIME ,'%Y-%m-%d') and DATE_FORMAT(date_add(a.END_TIME,interval -1 day),'%Y-%m-%d') ";
                        List<Map<String, Object>> rLog = JdbcUtil.exeSqlQuery(sql);
                        if(rLog!=null && rLog.size()>0){//不是历史的收益日期
                            startTime=(Date) (rLog.size()>0?rLog.get(0).get("startSettleDate"):startTime);
                            endTime=(Date) (rLog.size()>0?rLog.get(0).get("endSettleDate"):endTime);
                        }
                    }
                    swAuTvmShort.setIncomeSettleBeginTime(startTime);
                    swAuTvmShort.setIncomeSettleEndTime(endTime);

                    swAuTvmShort.setShortAmount(s.getDifferenceAmount().abs());
                    swAuTvmShort.setConductorPersonId(0);
                    swAuTvmShort.setConductorPerson(s.getConductorPersonName());
                    swAuTvmShort.setIsNotice(0);
                    swAuTvmShort.setIsSupPayment(0);
                    swAuTvmShort.setCreatorId(UserInfo.getId());
                    swAuTvmShort.setCreatorName(UserInfo.getName());
                    swAuTvmShort.setCreateTime(new Date());
                    swAuTvmShort.setUpdateTime(new Date());
                    swAuTvmShort.setSupPaymentTimelimit(new Date());
                    swAuTvmShort.setSupPaymentLimit(CheckAccount.getLimitTime("CONDUCTOR_REPLENISH_validity"));
                    int i = s.getDifferenceAmount().compareTo(new BigDecimal("0"));
                    //差异金额小于0时才加入到补款通知
                    if(i == -1){
                        if(swAuTvmShort.getId() != null){
                            swAuTvmShortMapper.updateById(swAuTvmShort);
                        }else {
                            swAuTvmShortMapper.insert(swAuTvmShort);
                        }
                    }
                }
            }
        }catch (Exception e){
            log.error("{}",e);
            res.setMsg("申诉回复失败");
            res.setResult(ResultDetailMsg.CHECK_UPDATE_ERROR);
        }
        return res;
    }


    /**
     * 通过id查询TVM票款差异确认通知
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}" )
    public R getById(@PathVariable("id" ) Integer id) {
        return R.ok(swAuTvmNoticeService.getById(id));
    }

    /**
     * 新增TVM票款差异确认通知
     * @param swAuTvmNotice TVM票款差异确认通知
     * @return R
     */
    @ApiOperation(value = "新增TVM票款差异确认通知", notes = "新增TVM票款差异确认通知")
    @SysLog("新增TVM票款差异确认通知" )
    @PostMapping
//    @PreAuthorize("@pms.hasPermission('generator_swautvmnotice_add')" )
    public R save(@RequestBody SwAuTvmNotice swAuTvmNotice) {
        log.info("新增TVM票款差异确认通知,swAuTvmNotice:{}", JSONObject.toJSONString(swAuTvmNotice));
        if (swAuTvmNotice.getRelationid() == null) {
            QueryWrapper<SwAuTvmAmountDefference> defferenceQueryWrapper = new QueryWrapper<>();
            defferenceQueryWrapper.eq("LINE_CODE", swAuTvmNotice.getLineCode());
            defferenceQueryWrapper.eq("STATION_CODE", swAuTvmNotice.getStationCode());
            defferenceQueryWrapper.eq("RECORD_TIME", swAuTvmNotice.getRecordTime());
            defferenceQueryWrapper.eq("TVM_CODE", swAuTvmNotice.getTvmCode());
            defferenceQueryWrapper.eq("DEL_FLAG", 0);
            List<SwAuTvmAmountDefference> swAuTvmAmountDefferences = swAuTvmAmountDefferenceMapper.selectList(defferenceQueryWrapper);
            if (CollectionUtils.isNotEmpty(swAuTvmAmountDefferences)) {
                SwAuTvmAmountDefference swAuTvmAmountDefference = swAuTvmAmountDefferences.get(0);
                swAuTvmNotice.setRelationid(swAuTvmAmountDefference.getId());
                swAuTvmAmountDefference.setNoticeSate("2");
                swAuTvmAmountDefferenceMapper.updateById(swAuTvmAmountDefference);
            } else {
                swAuTvmNotice.setRelationid(0);
            }
        }
        swAuTvmNotice.setDifferenceAmount(swAuTvmNotice.getDifferenceAmount().multiply(new BigDecimal("100")));
        swAuTvmNotice.setNoticeType("1");
        swAuTvmNotice.setDataSource("1");
        swAuTvmNotice.setNoticeState("1");
        swAuTvmNotice.setAppealStatus("1");
        swAuTvmNotice.setAppealType("1");
        swAuTvmNotice.setAuditSate("1");
        swAuTvmNotice.setSendStatus("1");
        swAuTvmNotice.setIsSupPayment(0);
        swAuTvmNotice.setReplyPeriod(CheckAccount.getConductorNoticeLimit()); //TODO 回复期限天数之后是不是改为配置的
        swAuTvmNotice.setSaleoperatorConfirmStatus("0");
        swAuTvmNotice.setCreatorName(UserInfo.getUserName());
        swAuTvmNotice.setCreatorId(UserInfo.getId());
        swAuTvmNotice.setCreateTime(new Date());
        return R.ok(swAuTvmNoticeMapper.insert(swAuTvmNotice));
    }

    /**
     * 修改TVM票款差异确认通知
     * @param swAuTvmNotice TVM票款差异确认通知
     * @return R
     */
    @ApiOperation(value = "修改TVM票款差异确认通知", notes = "修改TVM票款差异确认通知")
    @SysLog("修改TVM票款差异确认通知" )
    @PutMapping
//    @PreAuthorize("@pms.hasPermission('generator_swautvmnotice_edit')" )
    public R updateById(@RequestBody SwAuTvmNotice swAuTvmNotice) {
        swAuTvmNotice.setDifferenceAmount(swAuTvmNotice.getDifferenceAmount().multiply(new BigDecimal("100")));
        return R.ok(swAuTvmNoticeService.updateById(swAuTvmNotice));
    }

    /**
     * 通过id删除TVM票款差异确认通知
     * @param ids ids
     * @return R
     */
    @ApiOperation(value = "通过id删除TVM票款差异确认通知", notes = "通过id删除TVM票款差异确认通知")
    @SysLog("通过id删除TVM票款差异确认通知" )
    @GetMapping("/removeByIds" )
    public R removeById(@RequestParam(value = "ids") List<Integer> ids) {
        List<SwAuTvmNotice> swAuTvmNotices = swAuTvmNoticeMapper.selectBatchIds(ids);
        List<Integer> integerList = swAuTvmNotices.stream().map(SwAuTvmNotice::getRelationid).collect(Collectors.toList());
        swAuTvmNoticeMapper.deleteBatchIds(ids);
        LambdaUpdateWrapper<SwAuTvmAmountDefference> updateWrapper =
                Wrappers.<SwAuTvmAmountDefference>lambdaUpdate()
                        .set(SwAuTvmAmountDefference::getNoticeSate, "1")
                        .in(SwAuTvmAmountDefference::getId, integerList);
        swAuTvmAmountDefferenceMapper.update(null, updateWrapper);
        LambdaQueryWrapper<SwAuTvmShort> wrapper =
                Wrappers.<SwAuTvmShort>lambdaQuery().in(SwAuTvmShort::getNoticeId, ids);
        return R.ok(swAuTvmShortMapper.delete(wrapper));
    }

}
